package com.nulldev.util.crypto.api2.encryptors;

import java.nio.charset.Charset;

import com.nulldev.util.crypto.api2.Cryptable;
import com.nulldev.util.encoding.base64.Base64;

public class XOR extends Cryptable{

	public XOR() {
		super("XOR");
	}

	@Override
	public String encrypt(String object, String pass) {
		return this.encrypt(object, pass, null);
	}

	@Override
	public String decrypt(String object, String pass) {
		return this.decrypt(object, pass, null);
	}
	
	@Override
	public String encrypt(String object, String pass, Charset charset) {
		if (charset == null) {
			return base64Encode(xorWithKey(object.getBytes(), pass.getBytes()), null);
		}else {
			return base64Encode(xorWithKey(object.getBytes(charset), pass.getBytes()), charset);
		}
	}

	@Override
	public String decrypt(String object, String pass, Charset charset) {
		if (charset == null) {
			return new String(xorWithKey(base64Decode(object, null), pass.getBytes()));
		}else {
			return new String(xorWithKey(base64Decode(object, charset), pass.getBytes()));
		}
	}

    private static byte[] xorWithKey(byte[] a, byte[] key) {
        byte[] out = new byte[a.length];
        for (int i = 0; i < a.length; i++) {
            out[i] = (byte) (a[i] ^ key[i%key.length]);
        }
        return out;
    }

    private static byte[] base64Decode(final String s, final Charset charset) {
    	return Base64.decodeBase64(s, charset);//Base64Utils.encodeString(s).getBytes(CharsetUtil.getCharset());
    	//try {
    	//	return java.util.Base64.getDecoder().decode(s.getBytes(CharsetUtil.getCharset()));
    	//}catch (IllegalArgumentException e) {
    	//	throw new RuntimeException("[CryptoUtil] Failed to decode '" + s + "'. [" + e.getClass().getName() + " -> " + e.getMessage() + "]");
    	//}
    }

    private static String base64Encode(final byte[] bytes, final Charset charset) {
    	return Base64.encodeBase64String(bytes, charset);//Base64Utils.decodeString(new String(bytes, CharsetUtil.getCharset()));
    	//throw new UnsupportedOperationException("Unsupported Java release.");
		//byte[] new_string = java.util.Base64.getEncoder().encode(bytes);
		//return new String(new_string, CharsetUtil.getCharset());
    }
}
